home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / SNDLIST- / EDIT.C < prev    next >
Text File  |  1988-11-10  |  7KB  |  287 lines

  1. /*
  2.     Sound lister
  3.     "Edit.c"
  4. */
  5.  
  6. #include <DialogMgr.h>
  7. #include <EventMgr.h>
  8. #include <ResourceMgr.h>
  9. #include <SoundMgr.h>
  10. #include <ToolBoxUtil.h>
  11. #include "SndList.h"
  12.  
  13. /* ----- Globals ------------------------------------------------------- */
  14.  
  15. unsigned char *Rname;        /* Name of resource file */
  16. short Rvolume;                /* Volume reference of resource file */
  17. short Level;                /* Sound volume level */
  18. Handle Sound;                /* Current sound */
  19. short SndId;                /* Current 'snd ' resource id */
  20. Fixed *Rate;                /* Sampling rate in current sound */
  21. short *Note;                /* Base note in current sound */
  22.  
  23. /* ----- Calculate new rate -------------------------------------------- */
  24.  
  25. void Calc(rate, base)
  26. Fixed *rate;            /* Sampling rate */
  27. short *base;            /* Base note */
  28. {
  29.     double value, exp2();
  30.  
  31.     value = Fix2X(*rate);
  32.     value = value * exp2(5.0 - *base/12.0);
  33.     *rate = X2Fix(&value);
  34.     *base = 60;
  35. }
  36.  
  37. /* ----- Filter function for modal dialog ------------------------------ */
  38.  
  39. static pascal Boolean MyFilter(dialog, event, item)
  40. register DialogPtr dialog;
  41. register EventRecord *event;
  42. register short *item;
  43. {
  44.     register unsigned char key;
  45.  
  46.     switch (event->what) {
  47.         case updateEvt:
  48.             OutLine(dialog, 1, patCopy);
  49.             break;
  50.         case keyDown:
  51.         case autoKey:
  52.             key = event->message & charCodeMask;
  53.             if (key == '\r' || key == 0x03) {
  54.                 *item = 1;
  55.                 return TRUE;
  56.             }
  57.             if ((key < '0' || key > '9') && key != '.' &&
  58.                     key != '\t' && key != '\b') {
  59.                 SysBeep(1);
  60.                 event->what = nullEvent;
  61.             }
  62.             break;
  63.     }
  64.     return FALSE;    /* ModalDialog() should handle event */
  65. }
  66.  
  67. /* ----- Modify the 'snd ' resource in the file ------------------------ */
  68.  
  69. static short ModifySound()
  70. {
  71.     register Fixed rate;
  72.     register short note;
  73.     register long rateOffset, noteOffset;
  74.     register Handle h;
  75.     short current, ref, error;
  76.  
  77.     rate = *Rate;
  78.     note = *Note;
  79.     rateOffset = (Ptr)Rate - *Sound;
  80.     noteOffset = (Ptr)Note - *Sound;
  81.     DisposHandle(Sound);
  82.     if ((ref = OpenResources(Rname, Rvolume, ¤t)) == -1)
  83.         return ResError();
  84.     if (h = Get1Resource('snd ', SndId)) {
  85.         *(Fixed *)(*h + rateOffset) = rate;
  86.         *(short *)(*h + noteOffset) = note;
  87.         ChangedResource(h);
  88.         WriteResource(h);
  89.     }
  90.     error = ResError();
  91.     CloseResources(current, ref);
  92.     return error;
  93. }
  94.  
  95. /* ----- Check 'snd ' resource ----------------------------------------- */
  96.  
  97. enum {
  98.     check_Ok,
  99.     check_OpenErr,
  100.     check_GetErr,
  101.     check_SizeErr,
  102.     check_TypeErr,
  103.     check_CmdErr
  104. };
  105.  
  106. static short CheckSound()
  107. {
  108.     register Ptr max;
  109.     register short *p;
  110.     register SoundHeader *q;
  111.     register short i, n, command, type;
  112.     short current, ref;
  113.  
  114.     if ((ref = OpenResources(Rname, Rvolume, ¤t)) == -1)
  115.         return check_OpenErr;
  116.     if (Sound = Get1Resource('snd ', SndId)) {
  117.         DetachResource(Sound);
  118.         HNoPurge(Sound);
  119.         HLock(Sound);
  120.     }
  121.     CloseResources(current, ref);
  122.     if (!Sound)
  123.         return check_GetErr;
  124.  
  125.     p = (short *)(*Sound);
  126.     max = (Ptr)p + GetHandleSize(Sound);
  127.  
  128.     type = *p++;                /* Type of 'snd ' resource */
  129.     if ((Ptr)p >= max)
  130.         return check_SizeErr;
  131.  
  132.     if (type != 1 && type != 2)
  133.         return check_TypeErr;
  134.  
  135.     if (type == 1) {
  136.         n = *p++;            /* Number of modifiers/synthesizers */
  137.         if ((Ptr)p >= max)
  138.             return check_SizeErr;
  139.         p += 3*n;            /* Skip resource id/ init parm of mod/synt */
  140.         if ((Ptr)p >= max)
  141.             return check_SizeErr;
  142.         command = bufferCmd | setPtrBit;
  143.     }
  144.  
  145.     if (type == 2 ) {
  146.         p++;                /* Skip reference count */
  147.         if ((Ptr)p >= max)
  148.             return check_SizeErr;
  149.         command = soundCmd | setPtrBit;
  150.     }
  151.  
  152.     n = *p++;                /* Number of sound commands to follow */
  153.     for (i = 0; i < n && (Ptr)p < max; i++) {
  154.         if (((SndCommand *)p)->cmd == command) {
  155.             q = (SoundHeader *)(*Sound + ((SndCommand *)p)->param2);
  156.             if ((Ptr)q < ((Ptr)p + (n-i)*sizeof(SndCommand)) ||
  157.                 (Ptr)q >= max || (long)q & 1)
  158.                 return check_SizeErr;
  159.             Rate = &(q->sampleRate);
  160.             Note = &(q->baseNote);
  161.             return check_Ok;
  162.         }
  163.         p += sizeof(SndCommand)/2;
  164.     }
  165.     return check_CmdErr;
  166. }
  167.  
  168. /* ----- Edit 'snd ' resource ------------------------------------------ */
  169.  
  170. static void EditSound(name, bounds)
  171. unsigned char *name;    /* Pascal string */
  172. Rect *bounds;
  173. {
  174.     register DialogPtr dialog;
  175.     short item;
  176.     unsigned char s[256];
  177.     unsigned long x;
  178.     short error;
  179.     short xlevel;
  180.  
  181.     CenterDialog('DLOG', rEdit, bounds);
  182.     if (dialog = GetNewDialog(rEdit, 0L, -1L)) {
  183.         SetEText(dialog, eName, name);
  184.         SndId = Extract(name+1);
  185.         error = CheckSound();
  186.         if (Sound) {
  187.             NumToString((long)(*(short *)*Sound), s);
  188.             SetEText(dialog, eType, s);
  189.         }
  190.         if (!error) {
  191.             Fixed2String(*Rate, s);
  192.             SetEText(dialog, eRate, s);
  193.             NumToString((long)(*Note), s);
  194.             SetEText(dialog, eNote, s);
  195.         }
  196.         ShowWindow(dialog);
  197.         OutLine(dialog, 1, patCopy);
  198.         do {
  199.             ModalDialog(MyFilter, &item);
  200.             switch(item) {
  201.                 case ePlay:
  202.                 case eOk:
  203.                     if (Sound) {
  204.                         if (!error) {
  205.                             GetEText(dialog, eRate, s);
  206.                             String2Fixed(s, &x);
  207.                             if (x > 0x13880000 && x < 0x7FFF0000)
  208.                                 *Rate = x;
  209.                             Fixed2String(*Rate, s);
  210.                             SetEText(dialog, eRate, s);
  211.                             GetEText(dialog, eNote, s);
  212.                             StringToNum(s, &x);
  213.                             if (x >= 0 && x < 128)
  214.                                 *Note = (short)x;
  215.                             NumToString((long)(*Note), s);
  216.                             SetEText(dialog, eNote, s);
  217.                         }
  218.                         if (item == ePlay) {
  219.                             HideCursor();
  220.                             GetSoundVol(&xlevel);
  221.                             SetSoundVol(Level);
  222.                             SndPlay(0L, Sound, FALSE);
  223.                             SetSoundVol(xlevel);
  224.                             ShowCursor();
  225.                         }
  226.                     }
  227.                     break;
  228.                 case eCalc1:
  229.                 case eCalc2:
  230.                     if (!error) {
  231.                         GetEText(dialog, eNote, s);
  232.                         StringToNum(s, &x);
  233.                         if (x >= 0 && x < 128) {
  234.                             *Note = (short)x;
  235.                             Calc(Rate, Note);
  236.                             Fixed2String(*Rate, s);
  237.                             SetEText(dialog, eRate, s);
  238.                             NumToString((long)(*Note), s);
  239.                             SetEText(dialog, eNote, s);
  240.                         }
  241.                     }
  242.                     break;
  243.             }
  244.         } while (item != eOk && item != eCancel);
  245.         DisposDialog(dialog);
  246.         if (item == eOk && !error)
  247.             ModifySound();
  248.         if (Sound)
  249.             DisposHandle(Sound);
  250.     }
  251. }
  252.  
  253. /* ----- Edit all selected 'snd ' resources ---------------------------- */
  254.  
  255. void EditSnds(window)
  256. register DocumentPeek window;
  257. {
  258.     register ListHandle list;
  259.     Point myCell;                /* Current cell */
  260.     short  length;                /* Length of cell entry */
  261.     unsigned char fname[256];    /* Name of resource file */
  262.     unsigned char name[256];    /* Name of sound resource */
  263.     Rect bounds;                /* Where to put dialog */
  264.  
  265.     SetPort(window);
  266.     bounds = ((WindowPtr)window)->portRect;
  267.     LocalToGlobal(&topLeft(bounds));
  268.     LocalToGlobal(&botRight(bounds));
  269.  
  270.     GetWTitle(window, fname);
  271.     Rname = fname;
  272.     Rvolume = window->volume;
  273.     Level = 7 - GetCheck(window, iLevel);
  274.  
  275.     list = window->list;
  276.     InitCursor();
  277.     myCell.v = myCell.h = 0;
  278.     while(LGetSelect(TRUE, &myCell, list)) {
  279.         length = sizeof(name) - 1;
  280.         LGetCell(name+1, &length, myCell, list);
  281.         name[0] = length;
  282.         EditSound(name, &bounds);
  283.         LSetSelect(FALSE, myCell, list);    /* De-select the cell */
  284.         LNextCell(TRUE, TRUE, &myCell, list);
  285.     }
  286. }
  287.